package com.apes.fn.scm.crossCompany.transfer.service;

import com.alibaba.fastjson.JSONObject;
import com.apes.fn.scm.crossCompany.transfer.model.TransferProduct;
import com.apes.fn.scm.crossCompany.transfer.repository.TransferProductRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.MapUtil;
import com.apes.framework.util.ReflectUtil;
import com.apes.scm.account.account.repository.StockRepository;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.stock.model.Location;
import com.apes.scm.masterdata.stock.repository.LocationRepository;
import com.apes.scm.voucher.service.builder.CrossTransferVoucherBuilder;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 */
@Service("transferProductService")
public class TransferProductService extends DomainService {

    @Autowired
    private TransferProductRepository transferProductRepository;
    @Autowired
    private StockRepository stockRepository;
    @Autowired
    private PartyRoleRepository partyRoleRepository;

    // 创建
    public TransferProduct save(SimpleRequest request) {
        TransferProduct transferProduct = request.getO(TransferProduct.class);
        this.judgeRepeatData(transferProduct);
        transferProduct.setCreator(request.getPersonId());
        transferProduct.setCreateUid(request.getPerson());
        transferProduct.setLastUid(request.getPerson());
        transferProduct.setCreateDate(new Date());
        return transferProductRepository.saveAndFlush(transferProduct);
    }

    // 修改
    public TransferProduct update(SimpleRequest request) {
        TransferProduct batchDump = request.getO(TransferProduct.class);
        batchDump.setLastUid(request.getPerson());
        return transferProductRepository.saveAndFlush(batchDump);
    }

    // 重复数据判断
    private void judgeRepeatData(TransferProduct transferProduct) {
        Enumeration export = transferProduct.getExport();
        Enumeration reception = transferProduct.getReception();
        PartyRole supplier = transferProduct.getSupplier();
        List repeatData = new ArrayList();
        if (export == null && reception != null && supplier != null) {
            repeatData = transferProductRepository.findAll("SELECT * FROM TRANSFER_PRODUCT WHERE EXPORT IS NULL AND RECEPTION = '" + reception.getId() + "' AND SUPPLIER_ID = '" + supplier.getId() + "'");
        } else if (export != null && reception == null && supplier != null) {
            repeatData = transferProductRepository.findAll("SELECT * FROM TRANSFER_PRODUCT WHERE EXPORT = '"+ export.getId() +"' AND RECEPTION IS NULL AND SUPPLIER_ID = '" + supplier.getId() + "'");
        } else if (export == null && reception == null && supplier != null) {
            repeatData = transferProductRepository.findAll("SELECT * FROM TRANSFER_PRODUCT WHERE EXPORT IS NULL AND RECEPTION IS NULL AND SUPPLIER_ID = '" + supplier.getId() + "'");
        } else if (export != null && reception != null && supplier == null) {
            repeatData = transferProductRepository.findAll("SELECT * FROM TRANSFER_PRODUCT WHERE EXPORT = '"+ export.getId() +"' AND RECEPTION = '" + reception.getId() + "' AND SUPPLIER_ID IS NULL ");
        } else if (export != null && reception != null && supplier != null) {
            repeatData = transferProductRepository.findAll("SELECT * FROM TRANSFER_PRODUCT WHERE EXPORT = '"+ export.getId() +"' AND RECEPTION = '" + reception.getId() + "' AND SUPPLIER_ID = '"+ supplier.getId() +"'");
        } else if (export == null && reception == null && supplier == null) {
            throw new RuntimeException("调入、调出、供应商不能同时为空！");
        }

        if (repeatData.size() > 0) throw new RuntimeException("已存在对应数据");
    }

    // 因有效查询条件比较特殊, 造此方法特殊查询
    public Page<TransferProduct> findAll(SimpleRequest request) throws Exception {
        List<Map> filters = request.get("condition");
        for (int i = 0; i < filters.size(); i++) {
            Map filter = filters.get(i);
            String field = filter.get("field").toString();
            String value = filter.get("value").toString();
            if ("validCondi".equals(field)) {
                if ("0".equals(value)) {
                    filter.put("value", false);
                    filter.put("field", "valid");
                }
                if ("1".equals(value)) {
                    filter.put("value", true);
                    filter.put("field", "valid");
                }
                if ("9".equals(value)) filters.remove(i);
            } else if ("export_id".equals(field)) {
                filter.put("field", "export.id");
            } else if ("reception_id".equals(field)) {
                filter.put("field", "reception.id");
            } else if ("supplier_id".equals(field)) {
                filter.put("field", "supplier.id");
            }
        }
        Sort sort = new Sort(Sort.Direction.DESC, "supplier.id");
        return transferProductRepository.findAll(JpaDsl.toCriteria(filters), PageRequest.of(request.get("page"), request.get("size"), sort));
    }

    List<Map> findExportToDirectly(SimpleRequest request) {
        return transferProductRepository.findExportToDirectly();
    }

    List<Map> findExportNoDirectlyToAll(SimpleRequest request) {
        return transferProductRepository.findExportNoDirectlyToAll();
    }

    // 根据仓库转换运营模式
    public String accordLCompanyChangeOperation(SimpleRequest request) {
        return this.accordLCompanyChangeOperationInner(request.getJO().getString("id"));
    }

    private String accordLCompanyChangeOperationInner(String locationId) {
        Location location = SpringManager.getBean(LocationRepository.class).findOne(locationId);
        String shipOperation = SpringManager.getBean(CrossCompanyTransferNewService.class).queryOperationModel(location.getCompany());
        return "empower".equals(shipOperation)?"001073":"subsidiary".equals(shipOperation)?"001661":"001072";
    }

    // 根据调入、调出运营模式查询供应商
    public List<String> accordOperationFindSupplier(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        String exportOperation = getJO.getString("export");
        String receptionOperation = getJO.getString("reception");
        List<TransferProduct> transferProducts = transferProductRepository.findByALL(exportOperation, receptionOperation);

        List<Map> coverDataFormat = transferProducts.stream().map(transferProduct ->
                MapUtil.mapper("EXPORT", this.obtainObjValue(transferProduct.getExport(), "id"),
                        "RECEPTION", this.obtainObjValue(transferProduct.getReception(), "id"),
                        "SUPPLIER_ID", this.obtainObjValue(transferProduct.getSupplier(), "id")))
                .collect(Collectors.toList());

        return this.obtainSupplier(coverDataFormat);
    }

    // 根据 调入公司、调出公司 查询供应商
    public List<String> accordCompanyFindSupplier(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        String exportOperation = this.accordLCompanyChangeOperationInner(getJO.getString("fCompanyId"));
        String receptionOperation = this.accordLCompanyChangeOperationInner(getJO.getString("subCompanyId"));
        List<TransferProduct> transferProducts = transferProductRepository.findByALL(exportOperation, receptionOperation);

        // 这里数据格式返回的是 map???????????????
        List<Map> coverDataFormat = transferProducts.stream().map(transferProduct ->
                MapUtil.mapper("EXPORT", this.obtainObjValue(transferProduct.getExport(), "id"),
                        "RECEPTION", this.obtainObjValue(transferProduct.getReception(), "id"),
                        "SUPPLIER_ID", this.obtainObjValue(transferProduct.getSupplier(), "id")))
                .collect(Collectors.toList());
        return this.obtainSupplier(coverDataFormat);
    }

    // 调出方为直营 - 查询供应商
    public List<String> obtainExportDirectly() {
        return this.obtainSupplier(transferProductRepository.findExportToDirectly());
    }

    // 调出方非直营 - 获取供应商
    public List<String> obtainExportNonDirectly() {
        return this.obtainSupplier(transferProductRepository.findExportNoDirectlyToAll());
    }

    // 获取供应商
    private List<String> obtainSupplier(List<Map> transferProduct) {
        Map supplierIsnull = this.filterSupplierIsNull(transferProduct);
        List<String> suppliers = new ArrayList<>();
        if (!supplierIsnull.isEmpty()) {
            suppliers.add("existsSupplierNull");
        } else {
            suppliers = transferProduct.stream().map(supplier -> (supplier.get("SUPPLIER_ID").toString())).collect(Collectors.toList());
        }
        return suppliers;
    }

    // 过滤是否有供应商是否为空
    private Map filterSupplierIsNull(List<Map> transferProducts) {
        return transferProducts.stream().filter(filterSupplier -> {return StringUtils.isEmpty((filterSupplier).get("SUPPLIER_ID"));}).findAny().orElse(new HashMap());
    }

    // 根据对象获取值
    private String obtainObjValue(Object obj, String field) {
        if (Objects.isNull(obj)) return "";
        return ReflectUtil.getFieldValue(obj, field);
    }

    public Map accordOperationStock(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        String fLocationId = getJO.getString("fLocationId");
        String productId = getJO.getString("productId");
        List supplierIds = getJO.getJSONArray("supplierIds");
        if ("001073".equals(getJO.getString("pxport")) && !"001073".equals(getJO.getString("reception"))) {
            return stockRepository.availableStockSupplierContract(fLocationId, productId, supplierIds);
        } else {
            if (supplierIds.contains("existsSupplierNull")) return stockRepository.availableStockAllSupplier(fLocationId, productId);
            return stockRepository.availableStockSupplier(fLocationId, productId, supplierIds);
        }
    }
}

























